/*
 * Copyright the original author or authors.
 * 
 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.mozilla.org/MPL/MPL-1.1.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import com.bourre.transitions.IFrameListener;
import com.kairos.engine.RTBeacon;

/**
	 * {@code RTAnimation} interface provides basic rules that
	 * animation object may follow when dealing with a {@code RTBeacon}.
	 * {@code RTAnimation} is a {@code IFrameListener} witch extends
	 * controls that class have to provide.
	 * 
	 * <p>More than methods such {@code start}, {@code stop}, and
	 * {@code isPlaying}, a {@code RTAnimation} provides methods
	 * to swap the reference beacon of the object or to modify the local speed
	 * of the object animation.</p>
	 * 
	 * <p>See the {@code RTObject} class for a concret implementation
	 * of the {@code RTAnimation} interface. {@code RTObject} is
	 * an abstract implementation, so extend it to create your own real time
	 * animated objects.</p> 
	 * 
	 * @author 	Cédric Néhémie
	 * @see		IFrameListener
	 * @see		RTBeacon
	 * @see		RTObject
	 */
interface com.kairos.engine.RTAnimation extends IFrameListener 
{
		/**
		 * Defines on witch beacon instance the object will run.
		 * 
		 * <p>If the object is currently running the concret class
		 * have to unregister itself from the object beacon. If you omit
		 * to unregister the object, the {@code onEnterFrame} method
		 * will be called by the two beacon.</p>
		 * 
		 * <p>Use that method if you want to animate object independently
		 * of the global {@code RTBeacon} instance.</p>
		 * 
		 * <p>If the passed-in beacon is null the object have to throw
		 * an {@code Error}.</p>
		 * 
		 * <p>Subclass that don't support the {@code setFrameBeacon}
		 * method have to throw an {@code Error}.</p>
		 * 
		 * <p>The example below show how to implements the {@code setFrameBeacon}
		 * correctly in a concret {@code RTAnimation} class. That example is taken
		 * from the {@code RTObject} class.</p>
		 * 
		 * <code>public function setFrameBeacon ( beacon : RTBeacon ) : Void
		 * {
		 * 	if( !beacon ) 
		 * 		throw new Error ( "Trying to set a null beacon for " + this );
		 * 	
		 * 	if( _bIsPlaying )
		 * 	{ 
		 * 		stop();
		 * 		_oBeacon = beacon;
		 * 		start();
		 * 	}
		 * 	else
		 * 	{
		 * 		_oBeacon = beacon;
		 * 	}
		 * }
		 * </code>
		 * 
		 * @param 	beacon {@code RTBeacon} or subclass instance.
		 * @throws  Error The {@code setFrameBeacon}
		 * 			method isn't supported by the current object.
		 * @throws  Error The passed-in beacon is null.
		 */
		function setFrameBeacon( beacon : RTBeacon ) : Void;
		
		/**
		 * Returns the current beacon onto witch the object run.
		 * 
		 * <p>Subclass that don't support the {@code getFrameBeacon}
		 * method have to throw an {@code Error}.</p>
		 * 
		 * @return  {@code RTBeacon} used by the object.
		 * @throws  Error The {@code getFrameBeacon} method isn't
		 * 			supported by the current object.
		 */
		function getFrameBeacon() : RTBeacon;
		
		/**
		 * Defines the local speed factor for the current object. Local speed works
		 * as a multiplier for the time step value received from the beacon - as the
		 * {@code setGlobalSpeed} feature of the RTBeacon.
		 * 
		 * <p>The local and global speed works the same. Both they multiply the time
		 * step by their own speed value. Resulting that you can rescale time for
		 * a specific object or for all objects at the same time. The effects of
		 * both parameters are cumulated with all other time adjustments (time limit
		 * or smoothness).</p>
		 * 
		 * <p>Subclass can accept a value lower or equals than 0 if their equation
		 * could support it, in many case a value of 0 will stop the animation.
		 * All objects that don't support this feature have to throw
		 * an {@code Error}.</p>
		 * 
		 * <p>Subclass that don't support the {@code setLocalSpeed}
		 * method have to throw an {@code Error}.</p>
		 * 
		 * @param 	rate Float number used as multiplier for the current time step
		 * @throws  Error The {@code setLocalSpeed} method isn't supported
		 * 			by the current object.
		 * @throws  Error The value specified in {@code setLocalSpeed}
		 * 			isn't supported by the current object.	
		 */
		function setLocalSpeed ( rate : Number ) : Void;
			
		/**
		 * Returns the current local speed factor of the object.
		 * 
		 * <p>Subclass that don't support the {@code setLocalSpeed}
		 * method have to throw an {@code Error}.</p>
		 * 
		 * @return  {@code Number} local speed of the object.
		 * @throws  Error The {@code getLocalSpeed} method isn't supported
		 * 			by the current object.
		 */
		function getLocalSpeed () : Number;
		
		/**
		 * Starts the animation by register it to listen to the beacon
		 * {@code onEnterFrame} event.
		 * 
		 * <p>Any call of the {@code start} method when the object
		 * is playing have to be ignored.</p>
		 * 
		 * <p>The example below show a basic concret implementation of the
		 * {@code start} method. That example is taken from the 
		 * {@code RTObject} class.</p>
		 * 
		 * <code>public function start () : Void
		 * {
		 * 	if( !_bIsPlaying )
		 * 	{
		 * 		_bIsPlaying = true;
		 * 		_oBeacon.addFrameListener ( this );
		 * 	}
		 * }
		 * </code>
		 */
		function start () : Void;
		
		/**
		 * Stops the animation by register it to listen to the beacon
		 * {@code onEnterFrame} event.
		 * 
		 * <p>Any call of the {@code stop} method when the object
		 * isn't playing have to be ignored.</p>
		 * 
		 * <p>The example below show a basic concret implementation of the
		 * {@code stop} method. That example is taken from the 
		 * {@code RTObject} class.</p>
		 * 
		 * <code>public function stop () : Void
		 * {
		 * 	if( _bIsPlaying )
		 * 	{
		 * 		_bIsPlaying = false;
		 * 		_oBeacon.removeFrameListener ( this );
		 * 	}
		 * }
		 * </code>
		 */
		function stop () : Void;
		
		/**
		 * Returns {@code true} if the animation is playing, either {@code false}.
		 * 
		 * <p>An object is considered as playing if it have been plugged on the beacon, even
		 * if the beacon is stop itself. So use the {@code RTBeacon.stop} with care if
		 * you use it at the same time of any other time control solution.</p>
		 * 
		 * @return {@code true} if the animation is playing, either {@code false}.
		 */
		function isPlaying () : Boolean;
}